﻿using DG.Tweening;
using DG.Tweening.Core.Easing;
using GpuHud;
using System.Collections;
using System.Collections.Generic;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Profiling;

/// <summary>
/// 对于FlyText而言
/// Entity持有Accessor,创建时获取,析构时释放
/// Accessor是固定长度,
/// </summary>
public class GpuFlyTextEntity : GpuHudEntityBase
{
    public override GpuHudEntityType GetEntityType()
    {
        return GpuHudEntityType.FlyText;
    }

    #region 参数区
    public Vector3 initPos;
    public float duration;
    private bool isSelfDispose = false;
    GpuFlyTextAnim flyAnim;
    #endregion

    /// <summary>
    /// Init后处理
    /// </summary>
    /// <param name="gpuHudAsset"></param>
    protected override void LateInit()
    {
    }

    protected override void PrePlay()
    {
        //是否延迟set?
        m_gpuHudAccessor.Position = initPos;
    }
    protected override void LatePlay()
    {
        flyAnim = GpuHudAsset.m_TextAssetList[0].flyAnimType;
        isSelfDispose = (flyAnim != GpuFlyTextAnim.None);
    }

    protected override void LateUpdate()
    {
        //FlyText不需要更改位置,但是考虑
        //1. 是否需要CPU来算瓢字动画(如曲线位移/自定义动画),是的话可以加个控制开关
        //2. 判定延时,卸载
        //3. 好像只能在CPU端对缩放进行控制

        if (!isSelfDispose)
        {
            if (Time.time - StartTimestamp > duration)
            {
                BackPool();
                return;
            }
        }
        else
        {
            DoTweenAnimation();
        }
    }

    protected override void PreBackPool()
    {
        
    }

    protected override void LateOutPool()
    {
        
    }

    #region 缓动方法

    private void DoTweenAnimation()
    {
        switch (flyAnim)
        {
            case GpuFlyTextAnim.IntoUp:
                DoIntoUp_NoGC();
                break;
            case GpuFlyTextAnim.SkillLeft:
                DoSkillRight_NoGC();
                break;
            case GpuFlyTextAnim.SkillRight:
                DoSkillRight_NoGC();
                break;
            default:
                DoIntoUp_NoGC();
                break;
        }
    }

    private void DoIntoUp_NoGC()
    {
        float curDuration = Time.time - StartTimestamp;
        if (curDuration > 1.1 + GpuFlyTextHelper.frameTime * 15)
        {
            GpuHudFacade.GpuFacade.RecoverFlyTextEntity(this);
            //Debug.LogError("回池");
            return;
        }

        //stage1 - scale
        float endDuration = GpuFlyTextHelper.frameTime * 5;
        float innerDuration;
        if (curDuration < endDuration)
        {
            float endScale = EaseManager.Evaluate(Ease.Linear, null, curDuration, endDuration, 0, 0);
            m_gpuHudAccessor.SetTextScale(Mathf.Lerp(0.8f, 2f, endScale));
        }
        else
        {
            //subStage2
            float subDuration = GpuFlyTextHelper.frameTime * 2;
            if (curDuration < subDuration + endDuration)
            {
                float endScale = EaseManager.Evaluate(Ease.Linear, null, curDuration - endDuration, subDuration, 0, 0);
                m_gpuHudAccessor.SetTextScale(Mathf.Lerp(2f, 1f, endScale));
            }
            else
            {
                if (curDuration < subDuration + endDuration + GpuFlyTextHelper.frameTime * 2)
                    m_gpuHudAccessor.SetTextScale(1);
            }
        }

        //stage2 - position1
        endDuration = GpuFlyTextHelper.frameTime * 25;  // The sum of the endDuration of two stages
        if (curDuration < endDuration)
        {
            float v = EaseManager.Evaluate(Ease.OutCubic, null, curDuration, endDuration, 0, 0);
            float y = Mathf.Lerp(initPos.y, initPos.y + 15 * GpuFlyTextHelper.commonScaleFactory, v);
            m_gpuHudAccessor.SetTextPosition(new Vector3(initPos.x, y, initPos.z));
        }




        //satge3 - alpha
        endDuration = GpuFlyTextHelper.frameTime * 15;
        innerDuration = curDuration - 0.5f;
        if (innerDuration > 0)
        {
            if (innerDuration < endDuration)
            {
                float v = EaseManager.Evaluate(Ease.Linear, null, innerDuration, endDuration, 0, 0);
                float y = Mathf.Lerp(1, 0, v);
                m_gpuHudAccessor.SetTextAlpha(y);
            }
            else
            {
                if (innerDuration < endDuration + GpuFlyTextHelper.frameTime * 2)
                    m_gpuHudAccessor.SetTextAlpha(0);
            }
        }
    }


    /// <summary>
    /// 技能飘字右
    /// </summary>
    private void DoSkillRight_NoGC()
    {
        float curDuration = Time.time - StartTimestamp;
        if (curDuration > 1 + GpuFlyTextHelper.frameTime * 10)
        {
            GpuHudFacade.GpuFacade.RecoverFlyTextEntity(this);
            //Debug.LogError("回池");
            return;
        }

        //stage1 - scale Append模型 - N层嵌套大法
        float endDuration = GpuFlyTextHelper.frameTime * 5;
        float innerDuration;
        if (curDuration < endDuration)
        {
            float endScale = EaseManager.Evaluate(Ease.Linear, null, curDuration, endDuration, 0, 0);
            m_gpuHudAccessor.SetTextScale(Mathf.Lerp(0.8f, 3f, endScale));
        }
        else
        {
            //subStage2
            float subDuration = GpuFlyTextHelper.frameTime * 3;
            innerDuration = curDuration - endDuration;
            if (innerDuration < subDuration)
            {
                float endScale = EaseManager.Evaluate(Ease.Linear, null, innerDuration, subDuration, 0, 0);
                m_gpuHudAccessor.SetTextScale(Mathf.Lerp(3f, 1.5f, endScale));
            }
            else
            {
                float thirdDuration = GpuFlyTextHelper.frameTime * 3;
                innerDuration = curDuration - endDuration - subDuration;
                if (innerDuration < thirdDuration)
                {
                    float endScale = EaseManager.Evaluate(Ease.Linear, null, innerDuration, thirdDuration, 0, 0);
                    m_gpuHudAccessor.SetTextScale(Mathf.Lerp(1.5f, 1f, endScale));
                }
                else
                {
                    if (innerDuration < thirdDuration + GpuFlyTextHelper.frameTime * 2)
                        m_gpuHudAccessor.SetTextScale(1);
                }
            }
        }

        //stage2 - position2
        endDuration = GpuFlyTextHelper.frameTime * 10;
        innerDuration = curDuration - 1f;
        if (innerDuration > 0)
        {
            if (innerDuration < endDuration)
            {
                float v = EaseManager.Evaluate(Ease.InQuart, null, innerDuration, endDuration, 0, 0);
                float y = Mathf.Lerp(initPos.y, initPos.y + 5 * GpuFlyTextHelper.commonScaleFactory, v);
                m_gpuHudAccessor.SetTextPosition(new Vector3(initPos.x, y, initPos.z));
            }
            else
            {
                if (innerDuration < endDuration + GpuFlyTextHelper.frameTime * 2)
                    m_gpuHudAccessor.SetTextPosition(new Vector3(initPos.x, initPos.y + 5 * GpuFlyTextHelper.commonScaleFactory, initPos.z));
            }
        }

        //satge3 - alpha
        endDuration = GpuFlyTextHelper.frameTime * 10;
        innerDuration = curDuration - 1f;
        if (innerDuration > 0)
        {
            if (innerDuration < endDuration)
            {
                float v = EaseManager.Evaluate(Ease.Linear, null, innerDuration, endDuration, 0, 0);
                float y = Mathf.Lerp(1, 0, v);
                m_gpuHudAccessor.SetTextAlpha(y);
            }
            else
            {
                if (innerDuration < endDuration + GpuFlyTextHelper.frameTime * 2)
                    m_gpuHudAccessor.SetTextAlpha(0);
            }
        }
    }


    #endregion
}
